package com.gack.netty.handler;

import org.springframework.stereotype.Component;

import com.gack.netty.constant.ServerRequestMessageType;
import com.gack.netty.proto.MessageModule.Message;
import com.gack.netty.util.protoBuildUtil.MessageBuildUtil;

import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * 
* @ClassName: HeartbeatHandler 
* @Description: TODO(心跳检测handler) 
* @author (ZhangXinYu)  
* @date 2018年8月30日 下午2:03:59 
* @version V1.0
 */
@Component
@Sharable
@Slf4j
public class HeartbeatHandler extends ChannelInboundHandlerAdapter{

	@Override
	public void userEventTriggered (ChannelHandlerContext ctx, Object evt) throws Exception {
		if (evt instanceof IdleStateEvent) {
			IdleStateEvent idleStateEvent = (IdleStateEvent)evt;
//			String type = "";
//			if (idleStateEvent.state() == IdleState.READER_IDLE) {
//				type = "read idle";
//			} else if (idleStateEvent.state() == IdleState.WRITER_IDLE) {
//				type = "write idle";
//			} else if (idleStateEvent.state() == IdleState.ALL_IDLE) {
//				type = "all idle";
//			}
//			System.out.println("客户端["+ctx.channel().remoteAddress()+"] -- 心跳超时  -- 超时状态:"+type);
			// tail the client has time out of heartbeat
			// don't send message to client
			// Message callHeartbeatMessage = MessageBuildUtil.buildMessage("400", "place callback heartbeat");
			// ctx.channel().writeAndFlush(callHeartbeatMessage);
			// 这里可以使用一些心跳超时后的动作  如 为客户端下发通知 执行心跳机制  如果再次心跳超时则 为客户端发送提示 之后断开客户端连接
			if( idleStateEvent.state() == IdleState.READER_IDLE && !idleStateEvent.isFirst()){
				// not idle first , close channel
				Message closeClientChannelMessage = MessageBuildUtil.buildMessage(ServerRequestMessageType.HEARTBEAT_TIME_OUT_CODE, 
						"too long time to do nothing,the channel will be close");
				ctx.channel().writeAndFlush(closeClientChannelMessage).addListener(ChannelFutureListener.CLOSE);
				log.info("-------------------------INFO-------------------------");
				log.info("客户端 ["+ctx.channel().remoteAddress().toString()+"] 客户端两次心跳超时,服务器已主动断开与客户端的连接");
			}
		} else {
			super.userEventTriggered(ctx, evt);
		}
	}

}
